/**
 * copyright 2016 google inc.
 *
 * licensed under the apache license, version 2.0 (the "license");
 * you may not use this file except in compliance with the license.
 * you may obtain a copy of the license at
 *
 *     http://www.apache.org/licenses/license-2.0
 *
 * unless required by applicable law or agreed to in writing, software
 * distributed under the license is distributed on an "as is" basis,
 * without warranties or conditions of any kind, either express or implied.
 * see the license for the specific language governing permissions and
 * limitations under the license.
 */
'use strict';

class Logo{
  constructor(){

    this.pixels = [
      568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 661, 662, 663, 708,
      709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 801, 802, 803, 848, 849,
      850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 941, 942, 943, 988, 989, 990,
      1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,
      1048, 1049, 1081, 1082, 1083, 1128, 1129, 1130, 1175, 1176, 1177, 1178, 1179,
      1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1221, 1222, 1223,
      1268, 1269, 1270, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324,
      1325, 1326, 1327, 1328, 1329, 1361, 1362, 1363, 1372, 1373, 1374, 1375, 1376,
      1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1408, 1409, 1410, 1455, 1456,
      1457, 1467, 1468, 1469, 1501, 1502, 1503, 1512, 1513, 1514, 1515, 1516, 1517,
      1518, 1519, 1520, 1521, 1522, 1523, 1524, 1548, 1549, 1550, 1573, 1574, 1575,
      1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1595, 1596,
      1597, 1607, 1608, 1609, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623,
      1624, 1625, 1626, 1627, 1641, 1642, 1643, 1652, 1653, 1654, 1655, 1656, 1657,
      1658, 1659, 1660, 1661, 1662, 1663, 1664, 1684, 1685, 1686, 1687, 1688, 1689,
      1690, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724,
      1725, 1726, 1735, 1736, 1737, 1747, 1748, 1749, 1755, 1756, 1757, 1758, 1759,
      1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1781, 1782, 1783, 1792, 1793,
      1794, 1802, 1803, 1804, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1853, 1854,
      1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1875,
      1876, 1877, 1887, 1888, 1889, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902,
      1903, 1904, 1905, 1906, 1907, 1921, 1922, 1923, 1932, 1933, 1934, 1942, 1943,
      1944, 1945, 1946, 1947, 1948, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1993,
      1994, 1995, 2004, 2005, 2006, 2015, 2016, 2017, 2027, 2028, 2029, 2035, 2036,
      2037, 2045, 2046, 2047, 2061, 2062, 2063, 2072, 2073, 2074, 2082, 2083, 2084,
      2085, 2086, 2087, 2088, 2104, 2105, 2106, 2133, 2134, 2135, 2144, 2145, 2146,
      2152, 2153, 2154, 2155, 2156, 2157, 2164, 2165, 2166, 2167, 2168, 2169, 2175,
      2176, 2177, 2185, 2186, 2187, 2201, 2202, 2203, 2212, 2213, 2214, 2222, 2223,
      2224, 2225, 2226, 2227, 2228, 2244, 2245, 2246, 2273, 2274, 2275, 2284, 2285,
      2286, 2292, 2293, 2294, 2295, 2296, 2297, 2304, 2305, 2306, 2307, 2308, 2309,
      2315, 2316, 2317, 2325, 2326, 2327, 2341, 2342, 2343, 2352, 2353, 2354, 2366,
      2367, 2368, 2384, 2385, 2386, 2413, 2414, 2415, 2424, 2425, 2426, 2432, 2433,
      2434, 2435, 2436, 2437, 2444, 2445, 2446, 2447, 2448, 2449, 2455, 2456, 2457,
      2465, 2466, 2467, 2478, 2479, 2480, 2481, 2482, 2483, 2492, 2493, 2494, 2506,
      2507, 2508, 2524, 2525, 2526, 2550, 2551, 2552, 2553, 2554, 2555, 2564, 2565,
      2566, 2572, 2573, 2574, 2584, 2585, 2586, 2595, 2596, 2597, 2605, 2606, 2607,
      2608, 2609, 2610, 2611, 2618, 2619, 2620, 2621, 2622, 2623, 2632, 2633, 2634,
      2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647,
      2648, 2664, 2665, 2666, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682,
      2683, 2684, 2690, 2691, 2692, 2693, 2694, 2695, 2704, 2705, 2706, 2712, 2713,
      2714, 2724, 2725, 2726, 2735, 2736, 2737, 2745, 2746, 2747, 2748, 2749, 2750,
      2751, 2758, 2759, 2760, 2761, 2762, 2763, 2772, 2773, 2774, 2775, 2776, 2777,
      2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2804, 2805,
      2806, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2830,
      2831, 2832, 2833, 2834, 2835, 2844, 2845, 2846, 2852, 2853, 2854, 2864, 2865,
      2866, 2875, 2876, 2877, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2898, 2899,
      2900, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923,
      2924, 2925, 2926, 2927, 2928, 2944, 2945, 2946, 2954, 2955, 2956, 2957, 2958,
      2959, 2960, 2961, 2962, 2963, 2964, 2970, 2971, 2972, 2984, 2985, 2986, 2992,
      2993, 2994, 3004, 3005, 3006, 3015, 3016, 3017, 3029, 3030, 3031, 3038, 3039,
      3040, 3052, 3053, 3054, 3084, 3085, 3086, 3102, 3103, 3104, 3110, 3111, 3112,
      3124, 3125, 3126, 3132, 3133, 3134, 3144, 3145, 3146, 3155, 3156, 3157, 3169,
      3170, 3171, 3178, 3179, 3180, 3192, 3193, 3194, 3224, 3225, 3226, 3242, 3243,
      3244, 3250, 3251, 3252, 3264, 3265, 3266, 3272, 3273, 3274, 3284, 3285, 3286,
      3295, 3296, 3297, 3309, 3310, 3311, 3318, 3319, 3320, 3332, 3333, 3334, 3364,
      3365, 3366, 3382, 3383, 3384, 3390, 3391, 3392, 3404, 3405, 3406, 3412, 3413,
      3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426,
      3435, 3436, 3437, 3449, 3450, 3451, 3458, 3459, 3460, 3472, 3473, 3474, 3492,
      3493, 3494, 3504, 3505, 3506, 3522, 3523, 3524, 3530, 3531, 3532, 3544, 3545,
      3546, 3552, 3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563,
      3564, 3565, 3566, 3575, 3576, 3577, 3589, 3590, 3591, 3598, 3599, 3600, 3612,
      3613, 3614, 3632, 3633, 3634, 3644, 3645, 3646, 3662, 3663, 3664, 3670, 3671,
      3672, 3684, 3685, 3686, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700,
      3701, 3702, 3703, 3704, 3705, 3706, 3715, 3716, 3717, 3718, 3719, 3720, 3721,
      3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3738, 3739, 3740,
      3752, 3753, 3754, 3772, 3773, 3774, 3784, 3785, 3786, 3802, 3803, 3804, 3810,
      3811, 3812, 3824, 3825, 3826, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862,
      3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3878, 3879, 3880, 3892,
      3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905,
      3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913, 3914, 3924, 3925, 3926, 3942,
      3943, 3944, 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960,
      3961, 3962, 3963, 3964, 3965, 3966, 3995, 3996, 3997, 3998, 3999, 4000, 4001,
      4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4018, 4019, 4020,
      4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044,
      4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4064, 4065, 4066,
      4082, 4083, 4084, 4090, 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099,
      4100, 4101, 4102, 4103, 4104, 4105, 4106, 4149, 4150, 4151, 4158, 4159, 4160,
      4172, 4173, 4174, 4175, 4176, 4177, 4178, 4179, 4180, 4181, 4182, 4183, 4184,
      4185, 4186, 4187, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4204, 4205, 4206,
      4222, 4223, 4224, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239,
      4240, 4241, 4242, 4243, 4244, 4245, 4246, 4289, 4290, 4291, 4298, 4299, 4300,
      4344, 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, 4355, 4356,
      4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, 4429, 4430, 4431, 4438, 4439,
      4440, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493, 4494, 4495,
      4496, 4497, 4498, 4499, 4500, 4501, 4502, 4503, 4504, 4547, 4548, 4549, 4569,
      4570, 4571, 4578, 4579, 4580, 4581, 4582, 4583, 4584, 4585, 4586, 4587, 4624,
      4625, 4626, 4627, 4628, 4629, 4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637,
      4638, 4639, 4640, 4641, 4642, 4643, 4644, 4687, 4688, 4689, 4709, 4710, 4711,
      4718, 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4827, 4828, 4829,
      4849, 4850, 4851, 4858, 4859, 4860, 4861, 4862, 4863, 4864, 4865, 4866, 4867,
      4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979,
      4980, 4981, 4982, 4983, 4984, 4985, 4986, 4987, 4988, 4989, 4990, 4991, 5107,
      5108, 5109, 5110, 5111, 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, 5120,
      5121, 5122, 5123, 5124, 5125, 5126, 5127, 5128, 5129, 5130, 5131, 5247, 5248,
      5249, 5250, 5251, 5252, 5253, 5254, 5255, 5256, 5257, 5258, 5259, 5260, 5261,
      5262, 5263, 5264, 5265, 5266, 5267, 5268, 5269, 5270, 5271
    ]

    this.pixelSet = new Set(this.pixels)
  }

  randomSample(n){
    let l = this.pixels.length
    let samples = []
    for (let i=0; i<n; i++){
      samples.push(this.pixels[Math.floor(Math.random()*l)])
    }
    return samples
  }
}


function animation(G, info){
  if (info.debug){
    info.i += 1
    if (info.i % info.update === 0){
      console.log(
        'i', info.i,
        'ms/frame', (new Date() - info.time)/info.update,
        'num', G.particles.length
      )
      info.time = new Date()
    }
  }
  G.step()
  window.requestAnimationFrame(() => {animation(G, info)})
}

class Color{

  constructor(palettes, normalize){
    this.normalize = normalize
    this.palettes = palettes.map(p => p.map(rgb => rgb.map(r => r/255.0)))
    this.n = palettes.length
    this.i = 0
    this.p = this.palettes[0]
  }

  nextPalette(){
    this.i = (this.i+1)%this.n
    this.p = this.palettes[this.i]
  }

  getColorNormalizer(){

    let norm = this.normalize
    let c = this.p[Math.floor(Math.random()*this.p.length)]

    function normalize(i){
      i = norm(i)
      if (i<=0){
        return {
          r: 0,
          g: 0,
          b: 0
        }
      }
      return {
        r: Math.floor(i*c[0]),
        g: Math.floor(i*c[1]),
        b: Math.floor(i*c[2])
      }
    }

    return normalize

  }

}

function getNormalizeIntensity(lower, scale){

  function normalizeIntensity(i){
    if (i<=0){
      return 0
    }
    else if (i>=scale){
      return 255
    }

    return Math.floor(lower + (i/scale)*(255.0-lower))
  }

  return normalizeIntensity

}



module.exports = {
  Logo: Logo,
  Color: Color,
  getNormalizeIntensity: getNormalizeIntensity,
  animation: animation
}

